package com.nic.view.widget;

import android.content.Context;
import android.support.design.widget.TextInputEditText;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextWatcher;
import android.util.AttributeSet;

/**
 * @className 自定义控件 禁止输入表情符号
 */
public class ContainsEmojiEditText extends TextInputEditText {
    // 输入表情前的光标位置
    private int cursorPos;
    // 输入表情前EditText中的文本
    private String inputAfterText;
    // 是否重置了EditText的内容
    private boolean resetText;
    // 上下文对象
    private Context mContext;

    // 构造方法
    public ContainsEmojiEditText(Context context) {
        // 重写方法
        super(context);
        // 上下文对象复制操作
        this.mContext = context;
        // 初始化
        initEditText();
    }

    // 含参的构造方法
    public ContainsEmojiEditText(Context context, AttributeSet attrs) {
        // 重写方法
        super(context, attrs);
        // 上下文对象
        this.mContext = context;
        // 初始化
        initEditText();
    }

    public ContainsEmojiEditText(Context context, AttributeSet attrs,
                                 int defStyleAttr) {
        // 重写方法
        super(context, attrs, defStyleAttr);
        // 上下文对象
        this.mContext = context;
        // 初始化
        initEditText();
    }

    // 初始化edittext 控件
    private void initEditText() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start,
                                          int before, int count) {
                // 如果输入框未被重置
                if (!resetText) {
                    cursorPos = getSelectionEnd();
                    // 这里用s.toString()而不直接用s是因为如果用s，
                    // 那么，inputAfterText和s在内存中指向的是同一个地址，s改变了，
                    // inputAfterText也就改变了，那么表情过滤就失败了
                    inputAfterText = s.toString();
                }

            }

            // 文本变动监听事件
            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
                try {
                    if (!resetText) {
                        // 表情符号的字符长度最小为2
                        if (count >= 2) {
                            // 获取输入字符
                            CharSequence input = s.subSequence(cursorPos,
                                    cursorPos + count);
                            // 判断是否包含表情符号
                            if (containsEmoji(input.toString())) {
                                // 布尔值设置为true
                                resetText = true;
                                // 是表情符号就将文本还原为输入表情符号之前的内容
                                setText(inputAfterText);
                                // 获取文本
                                CharSequence text = getText();

                                if (text instanceof Spannable) {
                                    // 实例化文本
                                    Spannable spanText = (Spannable) text;
                                    // 设置
                                    Selection.setSelection(spanText,
                                            text.length());
                                }
                            }
                        }
                    } else {
                        // 设置布尔值为false
                        resetText = false;
                    }

                } catch (Exception e) {
                }

            }

            // 更改后监听事件
            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }

    /**
     * 检测是否有emoji表情
     *
     * @param source
     * @return
     */
    public static boolean containsEmoji(String source) {
        // 获取字符串的长度
        int len = source.length();
        // 遍历字符串
        for (int i = 0; i < len; i++) {
            // 获取字符
            char codePoint = source.charAt(i);
            // 如果不能匹配,则该字符是Emoji表情
            if (!isEmojiCharacter(codePoint)) {
                // 返回true
                return true;
            }
        }
        // 返回false
        return false;
    }

    /**
     * 判断是否是Emoji
     *
     * @param codePoint 比较的单个字符
     * @return
     */
    private static boolean isEmojiCharacter(char codePoint) {
        // 判断字符
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

}
